package engine.utils
{
	import ash.core.Entity;
	
	import engine.classes.enumerations.Axis;
	import engine.systems.group.Children;
	import engine.systems.group.Parent;
	import engine.systems.motion.motion.Motion;
	import engine.systems.render.render.Render;
	import engine.systems.spatial.spatial.Spatial;
	import engine.systems.spatial.sleep.Sleep;

	public class EntityUtils
	{
		/**
		 * Syncs a Spatial and Render components' values.
		 * 
		 * @param Spatial: The Spatial component to sync.
		 * @param Render: The Render component to sync.
		 * @param toRender: If true, syncs the Spatial to the Render. If false, sync the Render to the Spatial.
		 */
		public static function syncPositions(entity:Entity, toRender:Boolean = true):void
		{
			var spatial:Spatial = entity.get(Spatial);
			var render:Render = entity.get(Render);
			
			if(toRender)
			{
				spatial.x 			= render.display.x;
				spatial.y 			= render.display.y;
				spatial.rotation 	= render.display.rotation;
			}
			else
			{
				render.display.x 		= spatial.x;
				render.display.y 		= spatial.y;
				render.display.rotation = spatial.rotation;
			}
		}
		
		/**
		 * Stops all motion being applied to an Entity.
		 * 
		 * @param Entity: The Entity to stop.
		 * @param Axis: The axis to stop motion on.
		 */
		public static function stopMotion(entity:Entity, axis:int = 2):void
		{
			var motion:Motion = entity.get(Motion);
			
			switch(axis)
			{
				case Axis.X:
					motion.velocityX 		= 0;
					motion.accelerationX 	= 0;
					break;
				
				case Axis.Y:
					motion.velocityY 		= 0;
					motion.accelerationY 	= 0;
					break;
				
				case Axis.BOTH:
					motion.velocityX 		= 0;
					motion.velocityY 		= 0;
					motion.accelerationX 	= 0;
					motion.accelerationY 	= 0;
					break;
			}
		}
		
		public static function sleeping(entity:Entity):Boolean
		{
			if(entity.managedSleep) return entity.sleeping;
			else return entity.group.paused && !entity.ignoreGroup;
		}
		
		public static function paused(entity:Entity):Boolean
		{
			if(entity.managedSleep) return entity.paused;
			else return entity.group.paused;
		}
		
		public static function addParentChild(parent:Entity, child:Entity):void
		{
			var parentChildren:Children = parent.get(Children);
			var childParent:Parent 		= child.get(Parent);
			
			if(!parentChildren)
			{
				parentChildren = new Children();
				parent.add(parentChildren);
			}
			else
			{
				for each(var entity:Entity in parentChildren)
				{
					if(entity == child) return;
				}
			}
			
			if(!childParent)
			{
				childParent = new Parent();
				child.add(childParent);
			}
			else
			{
				var oldParentChildren:Children = childParent.parent.get(Children);
				for(var i:int = 0; i < oldParentChildren.children.length; i++)
				{
					if(oldParentChildren.children[i] == child)
					{
						oldParentChildren.children.splice(i, 1);
						break;
					}
				}
			}
			
			childParent.parent = parent;
			parentChildren.children.push(child);
			
			if(!child.get(Sleep))
			{
				child.sleeping 		= parent.sleeping;
				child.ignoreGroup 	= parent.ignoreGroup;
				child.paused		= parent.paused;
			}
			child.managedSleep = true;
		}
	}
}